/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Network;

/**
 *
 * @author hell
 */


import java.io.*;
import java.net.*;

import Main.*;

public class NetworkLayer implements Runnable {

    private static InetAddress group;
    
    private static MulticastSocket socket1; // It might be good idea to create separate sockets for sending a receiving.
    private static int CurrentPort = 0;
    
    private static byte[] buf;
    private static DatagramPacket recv;
    

    public static void InitSocket(String MGroup, int MPort, int TTL) {
        try {
            group = InetAddress.getByName(MGroup);
            CurrentPort = MPort;
            socket1 = new MulticastSocket(CurrentPort);
            socket1.joinGroup(group);
            // Socket configuration:
            socket1.setLoopbackMode(false);
            socket1.setTimeToLive(TTL);
            
            buf = new byte[socket1.getReceiveBufferSize()]; // Not sure about the size...
            Main.PrintDebug(3, "NetworkLayer: found receive buffer size: "+String.valueOf(socket1.getReceiveBufferSize()));
            recv = new DatagramPacket(buf, buf.length);
        } catch (UnknownHostException e) {
            Main.PrintDebug(8, "NetworkLayer: Unknown host "+MGroup); // *? Die() ? (depends on source of MGroup and MPort)
        } catch (java.io.IOException e) {
            Main.PrintDebug(9, "NetworkLayer: could not create multicast socket");
        }
    }

    /*public static MulticastSocket getSocket1() { // Temporary, for testing only.
        return socket1;
    }*/
    
    
    public void run() {
        // *? Is separate method for initialization needed?
        while (true) { // *? Something more suitable than 'true'?
            try {
                Main.PrintDebug(3, "NetworkLayer: waiting for packet");
                socket1.receive(recv);
            } catch (java.io.IOException e) {
                Main.PrintDebug(7, "NetworkLayer: error receiving data from socket");
                // *! Should stop the thread here.
            }
            try {
                DataReceived(recv.getData());
            } catch (java.io.IOException e) {
                Main.PrintDebug(7, "NetworkLayer: error processing received data");
            }
                    
        }
    }
    
    private static void DataReceived(byte[] d) throws IOException{ // It probably shouldn't receive IOException from ProcessPacket!
//        Main.PrintDebug(3, "NetworkLayer: data received: '"+Main.byteArrayToHexString(d)+"'");
        Main.PrintDebug(3, "NetworkLayer: data received");
        NetworkProtocol.ProcessPacket(d);
    }
    public static void SendData(byte[] d) throws IOException{ // IOException probably should be handled in Main
        Main.PrintDebug(3, "NetworkLayer: data being sent: '"+Main.byteArrayToHexString(d)+"'");
        //Main.PrintDebug(3, "NetworkLayer: data being sent");
        // DataReceived(d);
        DatagramPacket outdata = new DatagramPacket(d, d.length, group, CurrentPort);
        socket1.send(outdata);
    }
    
    // for leaving the group:  socket1.leaveGroup(group);
}

 
